connect (соединить): bool QObject::connect (
const QObject *sender, // Источник события.
const char *signal, // Сигнал.
const QObject *receiver, // Объект-приёмник сигнала.
const char *method, // Функция-обработчик.
Qt::ConnectionType type = Qt::AutoConnection
) const
Последний параметр определяет режим обработки:
Qt::DirectConnection -- событие обрабатывается сразу;
Qt::QueuedConnection -- событие ставится в общую очередь и будет
обработано только после всех сообщений, уже имеющихся в этой очереди;
Qt::AutoConnection -- если источник события находится в том же
потоке, что и приёмник, то будет использован режим
Qt::DirectConnection, в противном случае --
Qt::QueuedConnection.
Для определения сигнала и слота используются макросы SIGNAL и
SLOT. Например, мы хотим, чтобы текстовая метка label
(экземпляр класса QLabel) отображала позицию полосы прокрутки
scrollBar (экземпляр класса QScrollBar). В
документации на библиотеку Qt (открыв doc/html/index.html или
программу assistant) находим, что в классе QAbstractSlider,
потомком которого является QScrollBar, определён сигнал
void QAbstractSlider::valueChanged ( int value )оповещающий об изменении положения ползунка полосы прокрутки. Далее, в описании класса
QLabel находим, что изменение текста надписи
производится с помощью функции setText(строка) или
setNum(число). Тогда вызов метода connect должен
выглядеть следующим образом: QObject::connect(
scrollBar, // Источник события.
SIGNAL(valueChanged(int)), // Сигнал.
label, // Объект-приёмник сигнала.
SLOT( setNum(int) ) ); // Функция-обработчик.
Заметим, что параметрами сигнала и слота являются типы, а не переменные.
Количество параметров слота всегда не больше количества параметров сигнала. Соответствие между ними, как обычно, позиционное: при выполнении программы значением i-го параметра слота становится значение i-го параметра сигнала.
В объявлении класса методы-слоты необходимо указывать в разделе
public slots или private slots. Обычно в
программе используются стандартные сигналы, но если требуется определить
собственные, то их надо объявить в разделе signals. Например:
class MainWondow : public QMainWindow {
Q_OBJECT
.............
signals:
void mySignal();
private slots:
void onMySignal();
.............
Сигнал может быть "соединён" с другим сигналом, например:
connect( myButton,
SIGNAL( clicked() ),
this,
SIGNAL( buttonClicked() ) );
Один и тот же сигнал можно связать с несколькими слотами и/или другими сигналами. С одним и тем же слотом можно связать несколько сигналов. Можно указать несколько одинаковых "соединений": тогда одно событие вызовет генерацию нескольких сигналов.
Чтобы разорвать связь между сигналом и слотом, используется метод
disconnect:
bool QObject::disconnect ( const QObject *sender,
const char *signal,
const QObject *receiver,
const char *method ) [static]
В листинге 5 приведён текст небольшой программы, иллюстрирующей принцип
обработки нажатия на кнопку (экземпляр класса QPushButton), а на
рис. показано, как выглядит окно программы в системе Windows.
1 // Сигналы и слоты: кнопка в окне 2 3 #include <QApplication> 4 #include <QPushButton> 5 6 int main(int argc, char *argv[]) { 7 8 QApplication app(argc, argv); 9 10 QPushButton *button = new QPushButton( 11 QString::fromLocal8Bit("&Выход") ); // Кнопка. 12 button->setFont(QFont("Times", 16, QFont::Bold)); 13 QObject::connect( 14 button, // Источник сигнала. 15 SIGNAL(clicked()), // Сигнал о нажатии кнопки. 16 &app, // Приёмник сигнала. 17 SLOT( quit() ) ); // Функция-слот (обработчик события). 18 button->show(); 19 20 return app.exec(); 21 }Здесь мы разместили в окне обычную кнопку (10-11) с надписью "Выход" и связали её нажатие -- сигнал
clicked (15) -- с
функцией-обработчиком quit (17), которая завершает приложение
app. Заметим, что мы не создаём главное окно для кнопки, это будет
сделано автоматически (рис.).
Символ "&" перед буквой "В" в тексте надписи на кнопке (11)
позволяет активировать её не только по щелчку левой кнопкой мыши или нажатием
клавиши Enter, но также с помощью комбинации клавиш
Alt+в (к сожалению, только в режиме ввода кириллицы).